"""
Probe: Banking crisis sign flip mechanism
Why does old_dep → banking risk in non-OECD but not OECD?
"""
import sys
from pathlib import Path
import numpy as np
import pandas as pd

PROJECT = Path("/mnt/c/demographics_capital_flows")
sys.path.insert(0, str(PROJECT / "multilateral" / "src"))
from model import PanelGLS

df = pd.read_csv(PROJECT / "crises" / "data" / "processed" / "crises_panel.csv")
TABLE_DIR = PROJECT / "crises" / "output" / "tables"

OECD_38 = [
    "AUS","AUT","BEL","CAN","CHL","COL","CRI","CZE","DNK","EST",
    "FIN","FRA","DEU","GRC","HUN","ISL","IRL","ISR","ITA","JPN",
    "KOR","LVA","LTU","LUX","MEX","NLD","NZL","NOR","POL","PRT",
    "SVK","SVN","ESP","SWE","CHE","TUR","GBR","USA",
]

def stars(p):
    if p < 0.01: return '***'
    if p < 0.05: return '**'
    if p < 0.1: return '*'
    return ''

def run(data, dv, xvars, label):
    cols = [dv] + xvars + ['iso3', 'year']
    s = data[[c for c in cols if c in data.columns]].dropna()
    actual_x = [v for v in xvars if v in data.columns]
    if len(s) < 50 or len(actual_x) == 0:
        print(f"  SKIP {label}: {len(s)} obs, {len(actual_x)} vars")
        return None
    g = PanelGLS()
    g.fit(s[dv].values, s[actual_x].values, s['iso3'].values, s['year'].values)
    print(f"\n  {label} (N={g.n_obs}, {g.n_countries}c, R²={g.r_squared:.4f})")
    res = {'label': label, 'n': g.n_obs, 'nc': g.n_countries, 'r2': g.r_squared}
    for i, v in enumerate(actual_x):
        sig = stars(g.pvalues[i])
        print(f"    {v:30s} {g.beta[i]:10.5f} ({g.se[i]:.5f}) {sig:4s} p={g.pvalues[i]:.4f}")
        res[f'{v}_coef'] = g.beta[i]
        res[f'{v}_se'] = g.se[i]
        res[f'{v}_p'] = g.pvalues[i]
    return res

def main():
    print(f"Panel: {len(df)} obs, {df['iso3'].nunique()} countries")
    print(f"Banking crisis onsets: {df['banking_crisis_onset'].sum():.0f}")

    dv = 'banking_crisis_onset'
    ews_controls = ['rgdp_growth', 'inflation', 'ca_gdp', 'kaopen', 'nfa_gdp_lag']

    # Construct useful variables
    df['log_gdp_pc'] = np.log(df['gdp_pc_ppp'].clip(lower=100))
    df['old_dep_x_log_gdp'] = df['old_dep'] * df['log_gdp_pc']
    df['old_dep_x_trade'] = df['old_dep'] * df['trade_openness']
    df['old_dep_x_gross_liab'] = df['old_dep'] * df['gross_liab_gdp']
    df['old_dep_x_pension'] = df['old_dep'] * df['pension_spending_gdp']
    df['old_dep_x_reserves'] = df['old_dep'] * df['fx_reserves_gdp']

    oecd = df[df['iso3'].isin(OECD_38)]
    non_oecd = df[~df['iso3'].isin(OECD_38)]

    print(f"\n{'='*70}")
    print("PART 1: CONFIRM SIGN FLIP")
    print('='*70)

    for lbl, sub in [("Full", df), ("OECD", oecd), ("Non-OECD", non_oecd)]:
        run(sub, dv, ['old_dep', 'youth_dep'] + ews_controls, f"Baseline [{lbl}]")

    print(f"\n{'='*70}")
    print("PART 2: IS IT JUST INCOME?")
    print('='*70)

    for lbl, sub in [("Non-OECD", non_oecd), ("OECD", oecd)]:
        run(sub, dv, ['old_dep', 'youth_dep', 'log_gdp_pc'] + ews_controls,
            f"+ GDP/pc [{lbl}]")
        run(sub, dv, ['old_dep', 'youth_dep', 'log_gdp_pc', 'old_dep_x_log_gdp'] + ews_controls,
            f"+ GDP/pc interaction [{lbl}]")

    print(f"\n{'='*70}")
    print("PART 3: INCOME TERCILE SPLIT (Non-OECD)")
    print('='*70)

    non_oecd_valid = non_oecd.dropna(subset=['gdp_pc_ppp', dv])
    terciles = non_oecd_valid.groupby('iso3')['gdp_pc_ppp'].mean()
    t1, t2 = terciles.quantile(0.33), terciles.quantile(0.67)
    low_inc = terciles[terciles <= t1].index
    mid_inc = terciles[(terciles > t1) & (terciles <= t2)].index
    high_inc = terciles[terciles > t2].index
    print(f"  Income terciles: Low <${t1:.0f}, Mid ${t1:.0f}-${t2:.0f}, High >${t2:.0f}")
    print(f"  Countries: Low={len(low_inc)}, Mid={len(mid_inc)}, High={len(high_inc)}")

    for lbl, isos in [("Low-income non-OECD", low_inc), ("Mid-income non-OECD", mid_inc),
                       ("High-income non-OECD", high_inc)]:
        sub = non_oecd[non_oecd['iso3'].isin(isos)]
        run(sub, dv, ['old_dep', 'youth_dep'] + ews_controls, f"Baseline [{lbl}]")

    print(f"\n{'='*70}")
    print("PART 4: FINANCIAL DEPTH PROXY (gross liabilities, trade openness, reserves)")
    print('='*70)

    for lbl, sub in [("Non-OECD", non_oecd)]:
        run(sub, dv, ['old_dep', 'youth_dep', 'gross_liab_gdp'] + ews_controls,
            f"+ Gross liab [{lbl}]")
        run(sub, dv, ['old_dep', 'youth_dep', 'gross_liab_gdp', 'old_dep_x_gross_liab'] + ews_controls,
            f"+ Gross liab interaction [{lbl}]")
        run(sub, dv, ['old_dep', 'youth_dep', 'trade_openness'] + ews_controls,
            f"+ Trade openness [{lbl}]")
        run(sub, dv, ['old_dep', 'youth_dep', 'trade_openness', 'old_dep_x_trade'] + ews_controls,
            f"+ Trade interaction [{lbl}]")
        run(sub, dv, ['old_dep', 'youth_dep', 'fx_reserves_gdp'] + ews_controls,
            f"+ FX reserves [{lbl}]")
        run(sub, dv, ['old_dep', 'youth_dep', 'fx_reserves_gdp', 'old_dep_x_reserves'] + ews_controls,
            f"+ Reserves interaction [{lbl}]")

    print(f"\n{'='*70}")
    print("PART 5: PENSION SPENDING INTERACTION")
    print('='*70)

    for lbl, sub in [("Non-OECD", non_oecd), ("OECD", oecd)]:
        run(sub, dv, ['old_dep', 'youth_dep', 'pension_spending_gdp'] + ews_controls,
            f"+ Pension spending [{lbl}]")
        run(sub, dv, ['old_dep', 'youth_dep', 'pension_spending_gdp', 'old_dep_x_pension'] + ews_controls,
            f"+ Pension interaction [{lbl}]")

    print(f"\n{'='*70}")
    print("PART 6: Z POLYNOMIAL (Non-OECD)")
    print('='*70)

    run(non_oecd, dv, ['Z_1', 'Z_2', 'Z_3'] + ews_controls, "Z polynomial [Non-OECD]")
    run(non_oecd, dv, ['Z_1', 'Z_2', 'Z_3', 'log_gdp_pc'] + ews_controls, "Z + GDP/pc [Non-OECD]")
    run(oecd, dv, ['Z_1', 'Z_2', 'Z_3'] + ews_controls, "Z polynomial [OECD]")

    print("\n\nDone.")

if __name__ == "__main__":
    main()
